import json

from 加密.Crpty import Crpty
import time
import uuid
import Global
from urllib.parse import urlencode
import random
import hashlib

from HTTP.HttpUtil import HttpUtil
class VerifyUtil:
    def __init__(self):
        self.HOST = "http://148.70.0.172:62346"
        self.app_id = 10
        self.app_key="2xgoij8opvftxu7oyh293wo3aem5yvfu"
        self.HEART_TIME = 1800
        self.GetCardInfo_ID = 3 #取卡信息的云函数
        #自定义接口,如果未定义直接注释掉
        self.LOGIN_API = "xamZk78KMmWtbDQR"
        self.HEART_API = "5dCyxTHc7Y5pTEhA"
        self.GETUSER_API = "RAXcpGBZzsYmB2zE"
        self.UNBIND_API = "cCQisew4FaJ7GMNE"
        self.CLOUD_API = "sM7bY7XWh2ymAksT"

        self.RSA_KEY = '''-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2/+7Lfb3kFAe/XaO5Y0P4sJB
Hms3FKVEM1n9kyHZslUriPuMxwIrsgAPfIreG34mN5juSca2WDW2jkkEHc/DIB1y
WBXWh5qRR3cOyFQSrby3vi+WZD0DO3x6BobB4Wocm7Diqq1i5d/VwE275vl4hNm0
5NnBTW3kzK6WfS+AwQIDAQAB
-----END PUBLIC KEY-----'''



        self.token=None
        self.http =HttpUtil()

    def parse_json_to_dict(self,json_string):
        try:
            parsed_dict = json.loads(json_string)
            return parsed_dict
        except json.JSONDecodeError as e:
            print(f"JSON 解析错误: {e}")
            return None

    def get_sha256(self,input_string):
        sha256_hash = hashlib.sha256()
        sha256_hash.update(input_string.encode('utf-8'))
        hex_digest = sha256_hash.hexdigest()

        return hex_digest

    def build_query_string(self,params):
        sorted_params = dict(sorted(params.items()))
        return urlencode(sorted_params,safe='|:_.')#设置机器码中的特殊字符串不进行编码


    def extend_params(self,dict_params):
        #random_number = random.randint(10 ** 15, 10 ** 16 - 1)
        current_time_seconds = time.time()
        current_time_milliseconds = int(current_time_seconds * 1000)
        dict_params["timestamp"] = current_time_milliseconds
        dict_params["safeCode"] = str(uuid.uuid4()).replace('-', '')


    def GetSignature(self,param):
        signParam = param + "&timestamp=" + str(int(time.time())) + "&safe_code=" + str(uuid.uuid4()).replace('-', '')
        hash = Crpty.sha256(signParam)
        return signParam + "&signature=" +hash
    def Login(self, card):
        status_code = None
        try:
            if hasattr(self, "LOGIN_API"):
                url = self.HOST + "/api/single/" + self.LOGIN_API
            else:
                url = self.HOST + "/api/single/login"
            body = {"card": card, "mac": Global.GetMachineCode()}
            # 拓展业务参数（加入 `timestamp` 和 `safeCode`）
            self.extend_params(body)
            # 对参数字典排序
            sort_str = self.build_query_string(body)
            # 获取排序后字符串的SHA256签名 ( 记得在结尾拼接APPKEY )
            signature = self.get_sha256(sort_str + self.app_key)
            # 将签名字段拼接在已经排序后的字符串后面
            sort_str = sort_str + "&signature=" + signature
            enc_params = ''
            if self.RSA_KEY == None or self.RSA_KEY == '':
                enc_params = '&' + sort_str
            else:
                enc_params = "&params=" + Crpty.rsa_encrypt(self.RSA_KEY, sort_str)
            data = "appId=" + str(self.app_id) + enc_params
            headers = {"Content-Type": "application/x-www-form-urlencoded"}  # 修改为字典形式
            resp,status_code,erro = self.http.post(url, data, headers)  # 修改为传递headers字典
            try:
                if resp == None:
                    return False, "服务器异常,请联系管理员!"
                resp = json.loads(resp)
            except json.JSONDecodeError as e:
                resp = Crpty.rsa_decrypt(self.RSA_KEY, resp)
                resp = json.loads(resp)
            if "code" not in resp:
                return False, "登陆失败:该卡不可用"
            if resp["code"] != 1:
                return False, "Code:" + str(resp["code"]) + ",Msg:" + resp["msg"]
            self.token = resp["data"]["token"]
            return True, ""
        except Exception as e:
            Global.LOGE(f"[异常]->Login异常{e}")
        return False,"登陆异常"
    def UnBindCard(self,card):
        status_code = None
        if hasattr(self, "UNBIND_API"):
            url = self.HOST + "/api/single/" + self.UNBIND_API
        else:
            url = self.HOST + "/api/single/unbind"
        body = {"card": card, "newMac": Global.GetMachineCode()}
        # 拓展业务参数（加入 `timestamp` 和 `safeCode`）
        self.extend_params(body)
        # 对参数字典排序
        sort_str = self.build_query_string(body)
        # 获取排序后字符串的SHA256签名 ( 记得在结尾拼接APPKEY )
        signature = self.get_sha256(sort_str + self.app_key)
        # 将签名字段拼接在已经排序后的字符串后面
        sort_str = sort_str + "&signature=" + signature
        enc_params = ''
        if self.RSA_KEY == None or self.RSA_KEY == '':
            enc_params = '&' + sort_str
        else:
            enc_params = "&params=" + Crpty.rsa_encrypt(self.RSA_KEY, sort_str)
        data = "appId=" + str(self.app_id) + enc_params
        headers = {"Content-Type": "application/x-www-form-urlencoded"}  # 修改为字典形式
        resp,status_code,erro = self.http.post(url, data, headers)  # 修改为传递headers字典
        try:
            if resp == None:
                return False, "服务器异常,请联系管理员!"
            resp = json.loads(resp)
        except json.JSONDecodeError as e:
            resp = Crpty.rsa_decrypt(self.RSA_KEY, resp)
            resp = json.loads(resp)
        if "code" not in resp:
            return False, "登陆失败:该卡不可用"
        if resp["code"] != 1:
            return False, "Code:" + str(resp["code"]) + ",Msg:" + resp["msg"]
        return True, resp["msg"]

    def GetCardInfo(self,card):
        status_code = None
        try:
            if hasattr(self, "GETUSER_API"):
                url = self.HOST + "/api/single/" + self.GETUSER_API
            else:
                url = self.HOST + "/api/single/info"
            body = {"card": card, "token": self.token}
            # 拓展业务参数（加入 `timestamp` 和 `safeCode`）
            self.extend_params(body)
            # 对参数字典排序
            sort_str = self.build_query_string(body)
            # 获取排序后字符串的SHA256签名 ( 记得在结尾拼接APPKEY )
            signature = self.get_sha256(sort_str + self.app_key)
            # 将签名字段拼接在已经排序后的字符串后面
            sort_str = sort_str + "&signature=" + signature
            enc_params = ''
            if self.RSA_KEY == None or self.RSA_KEY == '':
                enc_params = '&' + sort_str
            else:
                enc_params = "&params=" + Crpty.rsa_encrypt(self.RSA_KEY, sort_str)
            data = "appId=" + str(self.app_id) + enc_params
            headers = {"Content-Type": "application/x-www-form-urlencoded"}  # 修改为字典形式
            resp,status_code,erro = self.http.post(url, data, headers)  # 修改为传递headers字典
            try:
                if resp == None:
                    return False, "服务器异常,请联系管理员!"
                resp = json.loads(resp)
            except json.JSONDecodeError as e:
                resp = Crpty.rsa_decrypt(self.RSA_KEY, resp)

                resp = json.loads(resp)
            if "code" not in resp:
                return False, "登陆失败:该卡不可用"
            if resp["code"] != 1:
                return False, "Code:" + str(resp["code"]) + ",Msg:" + resp["msg"]
            return True, resp["data"]
        except Exception as e:
            Global.LOGE(f"取卡信息异常:{e}")
        return False, "获取卡信息异常"



    def Heart(self):
        status_code = None
        if hasattr(self, "HEART_API"):
            url = self.HOST + "/api/single/" + self.HEART_API
        else:
            url = self.HOST + "/api/single/heart"

        body = {"token": self.token}
        # 拓展业务参数（加入 `timestamp` 和 `safeCode`）
        self.extend_params(body)
        # 对参数字典排序
        sort_str = self.build_query_string(body)
        # 获取排序后字符串的SHA256签名 ( 记得在结尾拼接APPKEY )
        signature = self.get_sha256(sort_str + self.app_key)
        # 将签名字段拼接在已经排序后的字符串后面
        sort_str = sort_str + "&signature=" + signature
        enc_params=''
        if self.RSA_KEY == None or self.RSA_KEY == '' :
            enc_params='&'+sort_str
        else:
            enc_params = "&params="+Crpty.rsa_encrypt(self.RSA_KEY, sort_str)
        data = "appId=" + str(self.app_id)+enc_params
        headers = {"Content-Type": "application/x-www-form-urlencoded"}  # 修改为字典形式
        resp,status_code,erro = self.http.post(url, data, headers)  # 修改为传递headers字典
        try:
            if resp==None :
                return False, "服务器异常,请联系管理员!"
            resp=json.loads(resp)
        except json.JSONDecodeError as e:
            resp=Crpty.rsa_decrypt(self.RSA_KEY,resp)
            resp = json.loads(resp)
        if "code" not in resp:
            return False, "该卡不可用"
        if resp["code"]!=1 :
            return False,"Code:"+str(resp["code"])+",Msg:"+resp["msg"]
        return True,""

    def cloudFunc(self,funcID,jsFuncName,jsParams=''):
        status_code = None
        #jsParams JS函数入参（按照顺序填写，如果有多个入参请使用 , 分割）
        if hasattr(self, "CLOUD_API"):
            url = self.HOST + "/api/expand/" + self.CLOUD_API
        else:
            url = self.HOST + "/api/expand/cloud-func"

        body = {"funcId": funcID,"jsFuncName":jsFuncName,"jsParams":jsParams,"token":self.token}
        # 拓展业务参数（加入 `timestamp` 和 `safeCode`）
        self.extend_params(body)
        # 对参数字典排序
        sort_str = self.build_query_string(body)
        # 获取排序后字符串的SHA256签名 ( 记得在结尾拼接APPKEY )
        signature = self.get_sha256(sort_str + self.app_key)
        # 将签名字段拼接在已经排序后的字符串后面
        sort_str = sort_str + "&signature=" + signature
        enc_params=''
        if self.RSA_KEY == None or self.RSA_KEY == '' :
            enc_params='&'+sort_str
        else:
            enc_params = "&params="+Crpty.rsa_encrypt(self.RSA_KEY, sort_str)
        data = "appId=" + str(self.app_id)+enc_params
        headers = {"Content-Type": "application/x-www-form-urlencoded"}  # 修改为字典形式
        resp,status_code,erro = self.http.post(url, data, headers)  # 修改为传递headers字典
        try:
            if resp==None :
                return False, "服务器异常,请联系管理员!"
            resp=json.loads(resp)
        except json.JSONDecodeError as e:
            resp=Crpty.rsa_decrypt(self.RSA_KEY,resp)
            resp = json.loads(resp)
        if "code" not in resp:
            return False, "该卡不可用"
        if resp["code"]!=1 :
            return False,"Code:"+str(resp["code"])+",Msg:"+resp["msg"]
        if "data" not in resp:
            return False, "服务器异常,请联系管理员!"
        else:
            data = resp["data"]
            try:
                resp = json.loads(data)
                return True,resp
            except  json.JSONDecodeError as e:
                return False, resp["data"]
        return False, resp["data"]